package com.eb.buybuybuy.filter;

import com.eb.buybuybuy.constant.Configuration;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@WebFilter("/api/*")
public class Filter1_Limit implements Filter {
    private Map<String, LinkedList<Long>> requestMap = new ConcurrentHashMap<>();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String ip = servletRequest.getRemoteAddr();

        LinkedList<Long> visitList;
        if (requestMap.containsKey(ip)) {
            visitList = requestMap.get(ip);
        } else {
            visitList = new LinkedList<>();
        }

        long now = System.currentTimeMillis();
        if (visitList.size() < Configuration.currentLimitingSize) {
            // 次数没有满，直接添加，放行
            visitList.addFirst(now);
            requestMap.put(ip, visitList);
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            Long lastTime = visitList.getLast();
            // 超过一秒
            if (now - lastTime >= 1000) {
                // 在时间规定外，放行，更新访问链表
                visitList.removeLast();
                visitList.addFirst(now);
                requestMap.put(ip, visitList);
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                // 在时间规定内，请求次数过多，不放行
                HttpServletResponse response = (HttpServletResponse) servletResponse;
                response.setStatus(429);
            }
        }
    }
}